package com.pearl.jacksonspringboot.demo.anno;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.fasterxml.jackson.databind.type.LogicalType;
import org.springframework.boot.jackson.JsonComponent;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author TD
 * @version 1.0
 * @date 2024/4/12
 */
@JsonComponent
public class ListToStringComponent {

    public static class ListToStringJsonDeserializer extends StdDeserializer<List> {

        public ListToStringJsonDeserializer() {
            super(String.class);
        }

        /**
         * 反序列化
         *
         * @param jsonParser             解析器
         * @param deserializationContext 上下文
         * @return 反序列化后的值
         * @throws IOException
         */
        @Override
        public List<String> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {

            if (jsonParser.hasToken(JsonToken.VALUE_NULL)) { // null 返回空集合
                return new ArrayList<>();
            } else if (jsonParser.hasToken(JsonToken.VALUE_STRING)) { // 当前是String类型
                String textValue = jsonParser.getText();// 原值
                // 空值返回空集合
                if (textValue.isEmpty() || _isBlank(textValue)) {
                    return new ArrayList<>();
                }
                // “,”分割，返回集合
                return StrUtil.split(textValue, StrUtil.COMMA, true, true);
            }
            throw JsonMappingException.from(jsonParser, "JSON有误");
        }

        public LogicalType logicalType() {
            return LogicalType.Textual;
        }

        public boolean isCachable() {
            return true;
        }

        public Object getEmptyValue(DeserializationContext ctxt) throws JsonMappingException {
            return "";
        }

        public List<?> deserializeWithType(JsonParser p, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException {
            return this.deserialize(p, ctxt);
        }
    }

    public static class ListToStringJsonSerializer extends StdSerializer<List> {

        public ListToStringJsonSerializer() {
            super(String.class, false);
        }

        /**
         * 序列化
         *
         * @param value              被序列化的值
         * @param jsonGenerator      生成器
         * @param serializerProvider 提供者
         * @throws IOException
         */
        @Override
        public void serialize(List value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            // 空集合值写入 “”
            if (CollUtil.isEmpty(value)) {
                jsonGenerator.writeString("");
            } else {
                // 写入转为“,”拼接的字符串
                String commaString = CollUtil.join(value, StrUtil.COMMA);
                jsonGenerator.writeString(commaString);
            }
        }

        public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException {
            this.visitStringFormat(visitor, typeHint);
        }
    }
}
